/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.voltor.core;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

/*
 * NMAP VoltorEntity Types
 *
 * As stated in the section called “VoltorEntity and OS classification (Class
 * lines)”, every reference fingerprint is classified with one or more device
 * types. This list contains the device types used by Nmap and the criteria for
 * classifying a device as each type. These same rules are used to classify the
 * device types in version detection; see the description of the d// field in
 * the section called “match Directive”.
 *
 * general purpose This category contains general-purpose operating systems like
 * Linux and Windows. In the nmap-service-probes file this class is indicated by
 * a lack of a d// field.
 *
 * bridge A bridge combines two or more subnetworks into one. With a bridge this
 * happens at a lower level than with a router. This category also includes
 * things like Ethernet-to-serial bridges.
 *
 * broadband router Devices in this category connect a network to the Internet
 * via cable, ADSL, fiber optics, etc. Some of these devices provide network
 * address translation, a firewall, port forwarding, or other services.
 *
 * firewall A firewall controls what traffic is allowed into or out of a
 * network. Some also have additional capabilities. This category doesn't
 * include general-purpose operating systems that happen to come with a
 * firewall, but it does include OS distributions purpose-built to work only as
 * a firewall.
 *
 * game console A video game console like the Xbox or PlayStation.
 *
 * hub A hub joins network segments by re-broadcasting all traffic. Hubs are
 * distinct from switches, which selectively transmit packets only to relevant
 * destinations.
 *
 * load balancer A device that distributes inbound traffic to multiple devices
 * to ease the load on those devices.
 *
 * media device This category includes all kinds of audiovisual equipment,
 * including portable music players, home audio systems, TVs, and projectors.
 *
 * PBX A private branch exchange, or PBX, routes telephone calls within a
 * private organization and connects them to the public telephone network or
 * VoIP.
 *
 * PDA A handheld computer. Devices that are also telephones go in the "phone"
 * category.
 *
 * phone A network-capable telephone that is not a VoIP phone. Devices in this
 * category are typically mobile phones.
 *
 * power-device Miscellaneous power devices like uninterruptable power supplies
 * and surge protectors.
 *
 * printer Network-enabled printers, including printers with an embedded print
 * server.
 *
 * print server A print server connects a printer to a network. Printers that
 * contain their own print server go in the "printer" category instead.
 *
 * proxy server Any kind of proxy, including web proxies and other servers that
 * cache data or understand high-level protocols.
 *
 * remote management Devices that allow servers or other equipment to be
 * monitored or managed remotely.
 *
 * router Routers connect multiple networks. They are distinct from hubs and
 * switches because they route packets between different networks as opposed to
 * extending one network.
 *
 * security-misc Any security device that doesn't fall into the “firewall”
 * category belongs in this category. This includes intrusion detection and
 * prevention systems.
 *
 * specialized The catch-all category. If a device doesn't fall into one of the
 * other categories, it is specialized. Examples in this category are diverse
 * and include such things as clocks, oscilloscopes, climate sensors, and more.
 *
 * storage-misc Data storage devices like tape decks and network-attached
 * storage appliances.
 *
 * switch A device that extends a network by selectively re-broadcasting
 * packets. Switches are distinct from hubs, which broadcast all packets.
 *
 * telecom-misc Devices used by telephone systems that aren't PBXs, like
 * voicemail and ISDN systems.
 *
 * terminal A device with a keyboard and monitor with the primary purpose of
 * communicating directly with a terminal server or mainframe.
 *
 * terminal server A device providing terminal facilities to clients over a
 * network.
 *
 * VoIP adapter A device that converts between voice over IP (VoIP) protocols
 * and normal telephone traffic. Also may convert different VoIP protocols.
 *
 * VoIP phone A phone capable of a VoIP protocol.
 *
 * WAP Wireless access points offer a wireless connection to a network. Most
 * work with radio technology like 802.11b but some use infra-red or something
 * else. Devices that could also be put in another category, like wireless
 * broadband routers, are put in the WAP category because WAPs require special
 * network considerations.
 *
 * webcam Any kind of camera that stores or transmits pictures or video. This
 * includes everything from consumer webcams to security system cameras.
 */
public class VoltorEntity {

    public static final String TYPE_DATABASE = "Database";
    public static final String TYPE_WEBSERVER = "Webserver";
    
    
    private String type = null; //TODO: make enum
    private String name = null;
    private String description = null;
    private String closedEntityImage = null;
    private String openedEntityImage = null;
    private List<VoltorEntity> childEntities = new ArrayList<VoltorEntity>();
    private List<DynamicProperty> extendedProperties = new ArrayList<DynamicProperty>();
    private List listeners = Collections.synchronizedList(new LinkedList());

    public VoltorEntity() {
        this("N/A", "N/A", "N/A");
    }

    public VoltorEntity(String type, String name, String description) {
        setType(type);
        setName(name);
        setDescription(description);
    }

    public void addPropertyChangeListener(PropertyChangeListener pcl) {
        listeners.add(pcl);
    }

    public void removePropertyChangeListener(PropertyChangeListener pcl) {
        listeners.remove(pcl);
    }

    private void fire(String propertyName, Object old, Object nue) {
        //Passing 0 below on purpose, so you only synchronize for one atomic call:
        PropertyChangeListener[] pcls = (PropertyChangeListener[]) listeners.toArray(new PropertyChangeListener[0]);
        for (int i = 0; i < pcls.length; i++) {
            pcls[i].propertyChange(new PropertyChangeEvent(this, propertyName, old, nue));
        }
    }

    public void addExtendedProperty(String name, String value) {
        extendedProperties.add(new DynamicProperty(name, value));
    }

    public List<DynamicProperty> getExtendedProperties() {
        return extendedProperties;
    }

    public void addChildEntity(VoltorEntity device) {
        childEntities.add(device);
    }

    public List<VoltorEntity> getChildEntities() {
        return childEntities;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        String oldName = this.name;
        this.name = name;
        fire("date", oldName, name);
    }

    /**
     * @return the description
     */
    public String getDescription() {
        return description;
    }

    /**
     * @param description the description to set
     */
    public void setDescription(String description) {
        String oldDescription = this.description;
        this.description = description;
        fire("date", oldDescription, description);

    }

    /**
     * @return the type
     */
    public String getType() {
        return type;
    }

    /**
     * @param type the type to set
     */
    public void setType(String type) {
        String oldType = this.type;
        this.type = type;
        fire("date", oldType, type);
    }

    /**
     * @return the deviceImage
     */
    public String getClosedEntityImage() {
        return closedEntityImage;
    }

    /**
     * @param deviceImage the deviceImage to set
     */
    public void setClosedEntityImage(String deviceImage) {
        this.closedEntityImage = deviceImage;
    }

    /**
     * @return the openedEntityImage
     */
    public String getOpenedEntityImage() {
        return openedEntityImage;
    }

    /**
     * @param openedEntityImage the openedEntityImage to set
     */
    public void setOpenedEntityImage(String openedEntityImage) {
        this.openedEntityImage = openedEntityImage;
    }
    
}
